
package com.tools.cleanmaster.controller;

import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio.Albums;
import android.provider.MediaStore.Images.Media;
import android.provider.MediaStore.Images.Thumbnails;
import android.text.TextUtils;

import com.tools.cleanmaster.bean.DeepTrashItem;
import com.tools.cleanmaster.model.TrashType;
import com.tools.cleanmaster.model.item.FileTrashItem;
import com.tools.cleanmaster.model.item.ImageTrashBucket;
import com.tools.cleanmaster.model.item.ImageTrashItem;
import com.tools.cleanmaster.model.item.TrashItem;
import com.tools.cleanmaster.model.item.VideoTrashItem;
import com.tools.cleanmaster.utils.FeatureConfig;
import com.tools.cleanmaster.utils.LogHelper;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 多媒体帮助类
 */
public class MediaHelper {
    private static final String EXTERNAL = "external";
    final String TAG = getClass().getSimpleName();

    static ContentResolver cr;

    // 缩略图列表
    HashMap<String, String> thumbnailList = new HashMap<String, String>();

    // 专辑列表
    List<HashMap<String, String>> albumList = new ArrayList<HashMap<String, String>>();

    HashMap<String, ImageTrashBucket> bucketList = new HashMap<String, ImageTrashBucket>();

    private static MediaHelper instance;

    private MediaHelper() {
    }

    public static synchronized MediaHelper getHelper(ContentResolver provider) {
        if (instance == null) {
            instance = new MediaHelper();
        }
        cr = provider;
        return instance;
    }

    /**
     * 得到缩略图
     */
    private void getThumbnail() {
        Cursor cursor = null;
        try {

            String[] projection = {
                    Thumbnails._ID, Thumbnails.IMAGE_ID, Thumbnails.DATA
            };
            cursor = cr.query(Thumbnails.EXTERNAL_CONTENT_URI, projection, null, null, null);
            getThumbnailColumnData(cursor);
        } catch (Exception e) {
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }

    /**
     * 从数据库中得到缩略图
     */
    private void getThumbnailColumnData(Cursor cur) {
        if (cur.moveToFirst()) {
            int _id;
            int image_id;
            String image_path;
            int _idColumn = cur.getColumnIndex(Thumbnails._ID);
            int image_idColumn = cur.getColumnIndex(Thumbnails.IMAGE_ID);
            int dataColumn = cur.getColumnIndex(Thumbnails.DATA);

            while (cur.moveToNext()) {
                _id = cur.getInt(_idColumn);
                image_id = cur.getInt(image_idColumn);
                image_path = cur.getString(dataColumn);
                thumbnailList.put("" + image_id, image_path);
            }
        }
    }

    /**
     * 从本地数据库中得到原图
     */
    private void getAlbumColumnData(Cursor cur) {
        if (cur.moveToFirst()) {
            int _id;
            String album;
            String albumArt;
            String albumKey;
            String artist;
            int numOfSongs;

            int _idColumn = cur.getColumnIndex(Albums._ID);
            int albumColumn = cur.getColumnIndex(Albums.ALBUM);
            int albumArtColumn = cur.getColumnIndex(Albums.ALBUM_ART);
            int albumKeyColumn = cur.getColumnIndex(Albums.ALBUM_KEY);
            int artistColumn = cur.getColumnIndex(Albums.ARTIST);
            int numOfSongsColumn = cur.getColumnIndex(Albums.NUMBER_OF_SONGS);

            while (cur.moveToNext()) {
                _id = cur.getInt(_idColumn);
                album = cur.getString(albumColumn);
                albumArt = cur.getString(albumArtColumn);
                albumKey = cur.getString(albumKeyColumn);
                artist = cur.getString(artistColumn);
                numOfSongs = cur.getInt(numOfSongsColumn);

                HashMap<String, String> hash = new HashMap<String, String>();
                hash.put("_id", _id + "");
                hash.put("album", album);
                hash.put("albumArt", albumArt);
                hash.put("albumKey", albumKey);
                hash.put("artist", artist);
                hash.put("numOfSongs", numOfSongs + "");
                albumList.add(hash);

            }
        }
    }

    /**
     * 是否创建了图片集
     */
    boolean hasBuildImagesBucketList = false;

    /**
     * 得到图片集
     */
    void buildImagesBucketList(boolean stopRequested, ImageScanCallBack callBack) {
        // 构造缩略图索引
        if (bucketList != null) {
            bucketList.clear();
        }
        if (thumbnailList != null) {
            thumbnailList.clear();
        }
        getThumbnail();
        Cursor cur = null;
        try {

            // 构造相册索引
            String columns[] = new String[] {
                    Media._ID, Media.BUCKET_ID, Media.PICASA_ID, Media.DATA, Media.DISPLAY_NAME,
                    Media.TITLE, Media.SIZE, Media.BUCKET_DISPLAY_NAME, Media.DATE_MODIFIED
            };

            cur = cr.query(Media.EXTERNAL_CONTENT_URI, columns, null, null, Media.DATE_MODIFIED + " DESC");

            if (cur == null) {
                return;
            }

            // 获取图片总数
            int totalNum = cur.getCount();
            if (totalNum == 0) {
                callBack.emptyCursor();
                return;
            }

            int index = 0;
            long totalSize = 0;
            if (cur.moveToFirst()) {
                // 获取指定列的索引
                int photoIDIndex = cur.getColumnIndexOrThrow(Media._ID);
                int photoPathIndex = cur.getColumnIndexOrThrow(Media.DATA);
                int photoNameIndex = cur.getColumnIndexOrThrow(Media.DISPLAY_NAME);
                int photoTitleIndex = cur.getColumnIndexOrThrow(Media.TITLE);
                int photoSizeIndex = cur.getColumnIndexOrThrow(Media.SIZE);
                int bucketDisplayNameIndex = cur.getColumnIndexOrThrow(Media.BUCKET_DISPLAY_NAME);
                int bucketIdIndex = cur.getColumnIndexOrThrow(Media.BUCKET_ID);
                int picasaIdIndex = cur.getColumnIndexOrThrow(Media.PICASA_ID);
                int lastModified = cur.getColumnIndexOrThrow(Media.DATE_MODIFIED);

                while (cur.moveToNext()) {

                    if (stopRequested) {
                        return;
                    }

                    String _id = cur.getString(photoIDIndex);
                    String name = cur.getString(photoNameIndex);
                    String path = cur.getString(photoPathIndex);
                    String title = cur.getString(photoTitleIndex);
                    long size = cur.getLong(photoSizeIndex);
                    String bucketName = cur.getString(bucketDisplayNameIndex);
                    String bucketId = cur.getString(bucketIdIndex);
                    String picasaId = cur.getString(picasaIdIndex);
                    long lastModify = cur.getLong(lastModified);
                    File file = new File(path);
                    if (file.exists()) {
                        totalSize += size;
                    } else {
                        continue;
                    }
                    if (TextUtils.isEmpty(bucketName)) {
                        bucketName = "";
                    }
                    ImageTrashBucket bucket = bucketList.get(bucketId);
                    if (bucket == null) {
                        bucket = new ImageTrashBucket();
                        bucket.id = bucketId;
                        bucketList.put(bucketId, bucket);
                        bucket.trashType = TrashType.IMAGE_FILE;
                        bucket.imageList = new ArrayList<ImageTrashItem>();
                        bucket.bucketName = bucketName;
                    }
                    bucket.count++;
                    bucket.size += size;
                    bucket.isSelectedDefault = bucket.isSelected = false;

                    ImageTrashItem imageItem = new ImageTrashItem();
                    imageItem.size = size;
                    imageItem.imageId = _id;
                    imageItem.imagePath = path;
                    imageItem.isSelectedDefault = imageItem.isSelected = false;
                    imageItem.thumbnailPath = thumbnailList.get(_id);
                    imageItem.takePhotoTime = lastModify;
                    bucket.imageList.add(imageItem);
                    if (FeatureConfig.DEBUG_LOG) {
                        LogHelper.i(TAG, "_id=" + _id + " name=" + name + " path=" + path
                                + " title=" + title + " size=" + size + " bucketName=" + bucketName
                                + " bucketId=" + bucketId + " picasaId=" + picasaId + "  lastModify=" + lastModify);
                    }

                    callBack.updateProgress(index, totalNum, path);
                    index++;
                }
            }

            hasBuildImagesBucketList = true;
            if (stopRequested) {
                return;
            }
            createBucke(callBack);
            callBack.endProgress(totalSize);

        } catch (Exception e) {
            callBack.emptyCursor();
        } finally {
            if (cur != null) {
                cur.close();
            }
        }
    }

    /**
     * 得到图片集
     */
    public void getImagesBucketList(boolean stopRequested,
                                    ImageScanCallBack callBack) {
        buildImagesBucketList(stopRequested, callBack);
    }

    private void createBucke(ImageScanCallBack callBack) {
        List<ImageTrashBucket> imageList = new ArrayList<ImageTrashBucket>();
        Iterator<Map.Entry<String, ImageTrashBucket>> itr = bucketList.entrySet().iterator();
        while (itr.hasNext()) {
            Map.Entry<String, ImageTrashBucket> entry = itr.next();
            imageList.add(entry.getValue());
        }
        if (imageList.size() > 0) {
            ImageTrashBucket camera = null;
            for (ImageTrashBucket imageTrashBucket : imageList) {
                if (imageTrashBucket == null) {
                    continue;
                }
                if ("Camera".equals(imageTrashBucket.bucketName)) {
                    camera = imageTrashBucket;
                }
                Collections.sort(imageTrashBucket.imageList);
            }
            Collections.sort(imageList, COUNT_COMPARATOR);
            if (camera != null) {
                imageList.remove(camera);
                imageList.add(0, camera);
            }
        }
        callBack.endAll(imageList);
    }

    /**
     * 图集图集中的图片数目倒序排序
     */
    public static final Comparator<ImageTrashBucket> COUNT_COMPARATOR = new Comparator<ImageTrashBucket>() {
        @Override
        public final int compare(ImageTrashBucket a, ImageTrashBucket b) {
            if (a == null || b == null) {
                return 0;
            }
            if (a.imageList == null) {
                return 1;
            }
            if (b.imageList == null) {
                return 0;
            }
            if (a.imageList.size() == b.imageList.size()) {
                return 0;
            } else if (a.imageList.size() < b.imageList.size()) {
                return 1;
            } else {
                return -1;
            }
        }
    };

    // 删除MediaStore中图片数据
    public void deleteMediaImage(List<TrashItem> items) {
        if (cr != null && items != null && !items.isEmpty()) {
            String where = Media._ID + " in (  ";
            int size = items.size();
            StringBuilder builder = new StringBuilder(size);
            builder.append(where);
            for (int i = 0; i < size; i++) {
                builder.append(((ImageTrashItem) items.get(i)).imageId);
                if (i < (size - 1)) {
                    builder.append(',');
                }
            }
            builder.append(")");
            try {
                cr.delete(Media.EXTERNAL_CONTENT_URI, builder.toString(), null);
            } catch (Exception e) {
                if (FeatureConfig.DEBUG_LOG) {
                    LogHelper.i(TAG, e.getMessage());
                }
            }
        }
    }

    // 删除MediaStore中视频数据
    public void deleteMediaVideo(List<TrashItem> items) {
        if (cr != null && items != null && !items.isEmpty()) {
            String where = MediaStore.Video.Media._ID + " in (  ";
            int size = items.size();
            StringBuilder builder = new StringBuilder(size);
            builder.append(where);
            for (int i = 0; i < size; i++) {
                TrashItem item = items.get(i);
                if (item instanceof VideoTrashItem) {
                    builder.append(((VideoTrashItem) item).mId);
                }
                if (i < (size - 1)) {
                    builder.append(',');
                }
            }
            builder.append(")");
            int count = 0;
            try {
                count = cr.delete(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, builder.toString(), null);

            } catch (Exception e) {
                e.printStackTrace();
            }
            if (FeatureConfig.DEBUG_LOG) {
                LogHelper.i(TAG, count + "");
            }
        }
    }

    /**删除WhatsApp中的视频数据*/
    public void deleteWhatsappVideo(List<DeepTrashItem> items) {
        if (cr != null && items != null && !items.isEmpty()) {
            String where = MediaStore.Video.Media._ID + " in (  ";
            int size = items.size();
            StringBuilder builder = new StringBuilder(size);
            builder.append(where);
            for (int i = 0; i < size; i++) {
                DeepTrashItem item = items.get(i);
                builder.append((item.mFilePath));
                if (i < (size - 1)) {
                    builder.append(',');
                }
            }
            builder.append(")");
            int count = 0;
            try {
                count = cr.delete(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, builder.toString(), null);

            } catch (Exception e) {
                e.printStackTrace();
            }
            if (FeatureConfig.DEBUG_LOG) {
                LogHelper.i(TAG, count + "");
            }
        }
    }

    /**删除WhatsApp中的图片数据*/
    public void deleteWhatsappImage(List<DeepTrashItem> items) {
        if (cr != null && items != null && !items.isEmpty()) {
            String where = Media._ID + " in (  ";
            int size = items.size();
            StringBuilder builder = new StringBuilder(size);
            builder.append(where);
            for (int i = 0; i < size; i++) {
                builder.append(items.get(i).mFilePath);
                if (i < (size - 1)) {
                    builder.append(',');
                }
            }
            builder.append(")");
            try {
                cr.delete(Media.EXTERNAL_CONTENT_URI, builder.toString(), null);
            } catch (Exception e) {
                if (FeatureConfig.DEBUG_LOG) {
                    LogHelper.i(TAG, e.getMessage());
                }
            }
        }
    }

    // 删除MediaStore中文件数据
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public void deleteLargeFile(List<TrashItem> items) {
        if (cr != null && items != null && !items.isEmpty()) {
            String where = MediaStore.Files.FileColumns._ID + " in (  ";
            int size = items.size();
            StringBuilder builder = new StringBuilder(size);
            builder.append(where);
            for (int i = 0; i < size; i++) {
                TrashItem item = items.get(i);
                if (item instanceof FileTrashItem) {
                    builder.append(((FileTrashItem) item).id);
                }
                if (i < (size - 1)) {
                    builder.append(',');
                }
            }
            builder.append(")");
            int count = 0;
            try {
                Uri filesUri = MediaStore.Files.getContentUri(EXTERNAL);
                count = cr.delete(filesUri, builder.toString(), null);

            } catch (Exception e) {
                e.printStackTrace();
            }
            if (FeatureConfig.DEBUG_LOG) {
                LogHelper.i(TAG, count + "");
            }
        }
    }
}
